package com.wwg.myapplication;

import android.content.Context;
import android.graphics.*;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.LinkedList;
import java.util.Random;

public class WaterRippleView extends View {
    // 波纹物理参数
    private static final int DAMPING = 96;        // 衰减系数 (0-100)
    private static final int WAVE_SPEED = 8;       // 波速 (1-10)
    private static final int MAX_RIPPLES = 5;      // 最大同时显示的波纹数

    // 渲染参数
    private Paint mPaint = new Paint();
    private Bitmap mRenderBitmap;
    private Canvas mRenderCanvas;
    private int[] mPixels;
    private int mWidth, mHeight;

    // 波纹物理场
    private float[][] mWaveGrid1;
    private float[][] mWaveGrid2;
    private boolean mCurrentGrid = true;
    private LinkedList<Ripple> mRipples = new LinkedList<>();

    // 光照参数
    private float mLightX = 0.3f;  // 光源X方向
    private float mLightY = 0.7f;  // 光源Y方向
    private float mLightZ = 0.5f;  // 光源高度

    // 新增自动生成相关变量
    private boolean mAutoGenerate = false;
    private long mLastAutoTime = 0;
    private static final long AUTO_INTERVAL = 2000; // 2秒生成一次


    public WaterRippleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        mPaint.setAntiAlias(true);
        mPaint.setFilterBitmap(true);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;

        // 创建渲染缓冲
        mRenderBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mRenderCanvas = new Canvas(mRenderBitmap);
        mPixels = new int[w * h];

        // 初始化波纹网格
        mWaveGrid1 = new float[w][h];
        mWaveGrid2 = new float[w][h];

        // 设置默认背景
        mRenderCanvas.drawColor(0xFF2196F3); // 蓝色背景
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            addRipple(event.getX(), event.getY(), 15f); // 添加新波纹
            return true;
        }
        return super.onTouchEvent(event);
    }

    private void addRipple(float x, float y, float strength) {
        // 限制最大波纹数量
        if (mRipples.size() >= MAX_RIPPLES) {
            mRipples.removeFirst();
        }

        // 添加新波纹
        mRipples.add(new Ripple(x, y, strength, System.currentTimeMillis()));

        // 在物理网格中添加扰动
        int ix = (int) x, iy = (int) y;
        if (ix >= 0 && ix < mWidth && iy >= 0 && iy < mHeight) {
            mWaveGrid1[ix][iy] = strength;
        }

        invalidate(); // 触发重绘
    }

    // 新增自动生成控制方法
    public void setAutoGenerate(boolean autoGenerate) {
        mAutoGenerate = autoGenerate;
        if (autoGenerate) {
            mLastAutoTime = System.currentTimeMillis();
            invalidate();
        }
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // 1. 更新波纹物理场
        updateWaveField();

        // 2. 渲染波纹效果
        renderWaterSurface();

        // 3. 绘制到屏幕
        canvas.drawBitmap(mRenderBitmap, 0, 0, mPaint);

        // 4. 自动生成波纹逻辑
        if (mAutoGenerate) {
            long currentTime = System.currentTimeMillis();
            if (currentTime - mLastAutoTime > AUTO_INTERVAL) {
                generateRandomRipple();
                mLastAutoTime = currentTime;
            }
        }

        // 5. 持续动画
        postInvalidateDelayed(16); // 约60FPS
    }
    // 新增随机波纹生成方法
    private void generateRandomRipple() {
        if (mWidth == 0 || mHeight == 0) return;

        Random rand = new Random();
        float x = rand.nextInt(mWidth);
        float y = rand.nextInt(mHeight);
        float strength = 10 + rand.nextFloat() * 15; // 强度范围 10-25
        addRipple(x, y, strength);
    }

    private void updateWaveField() {
        float[][] current = mCurrentGrid ? mWaveGrid1 : mWaveGrid2;
        float[][] next = mCurrentGrid ? mWaveGrid2 : mWaveGrid1;

        // 更新波纹物理场
        for (int x = 1; x < mWidth - 1; x++) {
            for (int y = 1; y < mHeight - 1; y++) {
                // 波动方程: new = (current(x-1,y) + current(x+1,y) 
                //          + current(x,y-1) + current(x,y+1)) / 2 - next(x,y)
                float sum = current[x-1][y] + current[x+1][y]
                        + current[x][y-1] + current[x][y+1];

                next[x][y] = (sum / 2 - next[x][y]) * (1 - DAMPING/100f);
            }
        }

        // 边界归零
        for (int x = 0; x < mWidth; x++) {
            next[x][0] = 0;
            next[x][mHeight-1] = 0;
        }
        for (int y = 0; y < mHeight; y++) {
            next[0][y] = 0;
            next[mWidth-1][y] = 0;
        }

        mCurrentGrid = !mCurrentGrid; // 交换缓冲区
    }

    private void renderWaterSurface() {
        float[][] heightMap = mCurrentGrid ? mWaveGrid1 : mWaveGrid2;

        // 获取背景像素
        mRenderBitmap.getPixels(mPixels, 0, mWidth, 0, 0, mWidth, mHeight);

        // 计算法线并渲染
        for (int x = 1; x < mWidth - 1; x++) {
            for (int y = 1; y < mHeight - 1; y++) {
                // 计算法向量
                float dx = heightMap[x+1][y] - heightMap[x-1][y];
                float dy = heightMap[x][y+1] - heightMap[x][y-1];

                // 标准化法向量
                float len = (float) Math.sqrt(dx*dx + dy*dy + 1);
                float nx = dx / len;
                float ny = dy / len;
                float nz = 1 / len;

                // 计算光照 (Lambert模型)
                float dot = nx * mLightX + ny * mLightY + nz * mLightZ;
                dot = Math.max(0.2f, dot); // 最小亮度

                // 获取原始颜色
                int color = mPixels[y * mWidth + x];
                int r = (color >> 16) & 0xFF;
                int g = (color >> 8) & 0xFF;
                int b = color & 0xFF;

                // 应用光照
                r = (int) (r * dot);
                g = (int) (g * dot);
                b = (int) (b * dot);

                // 添加水蓝色调
                b = Math.min(255, b + 20);
                g = Math.min(255, g + 10);

                // 更新像素
                mPixels[y * mWidth + x] = 0xFF000000 | (r << 16) | (g << 8) | b;
            }
        }

        // 更新位图
        mRenderBitmap.setPixels(mPixels, 0, mWidth, 0, 0, mWidth, mHeight);
    }

    // 波纹数据结构
    private static class Ripple {
        float x, y;         // 中心位置
        float strength;     // 初始强度
        long startTime;     // 创建时间

        Ripple(float x, float y, float strength, long startTime) {
            this.x = x;
            this.y = y;
            this.strength = strength;
            this.startTime = startTime;
        }
    }
}